from __future__ import with_statement
"""
Created on 30-Nov-2009

@author: dexen
"""

import sys
import time
from threading import Lock
import multiprocessing as mp

import rpyc
from rpyc.utils import server

import dexen
from dexen.system.common import service
from dexen.system.common.service import DexenAddr
from dexen.system.registry.core import RegistryCore

#===============================================================================
# Globals
#===============================================================================
core = RegistryCore()
lock = Lock()


#===============================================================================
# Service Class
#===============================================================================
class RegistryService(dexen.Service): 
    def on_disconnect(self):
        #print "I am disconnected"
        pass
            
    def on_connect(self):
        #print "I am connected"
        pass
    
    def register_server(self, stime, addr):
        addr = rpyc.classic.obtain(addr)
        assert isinstance(addr, DexenAddr)
        core.register_server(addr)
        
    def get_server_addr(self):
        return core.get_server_addr()
        
    def register_node(self, stime, addr):
        with lock:
            addr = rpyc.classic.obtain(addr)
            assert isinstance(addr, DexenAddr)
            return core.register_node(addr)
    
    def get_new_nodes(self):
        with lock:
            return core.get_new_nodes()
    
    def register_master(self, name, addr):
        with lock:
            addr = rpyc.classic.obtain(addr)
            assert isinstance(addr, DexenAddr)
            core.register_master(name, addr)
            
    def get_master_addr(self, name):
        with lock:
            return core.get_master_addr(name)
    
    def register_slave(self, name, addr):
        with lock:
            addr = rpyc.classic.obtain(addr)
            assert isinstance(addr, DexenAddr)
            core.register_slave(name, addr)
            
    def get_slave_addr(self, name):
        with lock:
            return core.get_slave_addr(name)
            

def _start_naming_server(is_quiet):
    import rpyc_naming_registry
    rpyc_naming_registry.start(is_quiet)
     
    
def start(reg_name, is_quiet):
    if not service.is_local(reg_name) and reg_name != "unassigned":
        _auto_register = True
        p = mp.Process(target=_start_naming_server, args=(is_quiet,))
        p.daemon = True
        p.start()
        #To give some time to the rpyc registry to start so that the dexen
        #registry can register with the rpyc registry as soon as it is started.
        time.sleep(5) 
    else:
        _auto_register = False
    RegistryService.ALIASES = [reg_name]
    _logger = service.get_rpyc_logger(reg_name.upper(), is_quiet=is_quiet)
    svr = server.ThreadedServer(RegistryService, 
                                port=service.REGISTRY_PORT,
                                protocol_config=service.default_config,
                                auto_register=_auto_register,
                                logger=_logger)
    #At this point, the rpyc naming registry is assumed to have already started.
    #To achieve this, 5 seconds sleep statement is put above.
    svr.start()

    
#===============================================================================
# Main
#===============================================================================
def main():
    pass

if __name__ == "__main__":
    main()
